package com.example.workflow.service.impl;

import com.example.workflow.entity.SysProcess;
import com.example.workflow.mapper.SysProcessMapper;
import com.example.workflow.service.SysProcessService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.transaction.annotation.Transactional;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.apache.commons.io.IOUtils;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import com.example.workflow.vo.ProcessDetailVO;
import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
public class SysProcessServiceImpl implements SysProcessService {
    private final SysProcessMapper processMapper;
    private final RepositoryService repositoryService;
    
    @Override
    public List<SysProcess> listBySystemId(Long systemId) {
        return processMapper.selectBySystemId(systemId);
    }
    
    @Override
    public void addProcess(SysProcess process) {
        process.setCreateTime(new Date());
        process.setUpdateTime(new Date());
        process.setDelFlag(0);
        processMapper.insert(process);
    }
    

    
    @Override
    public void deleteProcess(Long id) {
        SysProcess process = new SysProcess();
        process.setId(id);
        process.setDelFlag(1);
        process.setUpdateTime(new Date());
        processMapper.updateById(process);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysProcess deployProcess(Long systemId, String name, String key, MultipartFile file) throws Exception {
        // 1. 验证文件
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("流程文件不能为空");
        }
        
        // 2. 部署流程
        Deployment deployment = repositoryService.createDeployment()
                .addInputStream(file.getOriginalFilename(), file.getInputStream())
                .name(name)
                .key(key)
                .deploy();
                
        // 3. 获取流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();
        
        if (processDefinition == null) {
            throw new RuntimeException("流程部署失败");
        }
        
        // 4. 保存流程信息到系统表
        SysProcess process = new SysProcess();
        process.setSystemId(systemId);
        process.setProcessName(name);
        process.setProcessKey(key);
        process.setDeploymentId(deployment.getId());
        process.setProcessDefinitionId(processDefinition.getId());
        process.setVersion(processDefinition.getVersion());
        process.setCreateTime(new Date());
        process.setUpdateTime(new Date());
        process.setDelFlag(0);
        process.setStatus(1);
        
        processMapper.insert(process);
        
        return process;
    }

    @Override
    public ProcessDetailVO getProcessDetail(Long id) throws Exception {
        // 1. 获取流程信息
        SysProcess process = processMapper.selectById(id);
        if (process == null) {
            throw new RuntimeException("流程不存在");
        }

        // 2. 获取XML内容
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(process.getProcessDefinitionId())
                .singleResult();
        
        if (processDefinition == null) {
            throw new RuntimeException("流程定义不存在");
        }

        InputStream xmlStream = repositoryService.getResourceAsStream(
                processDefinition.getDeploymentId(), 
                processDefinition.getResourceName());
        
        String xml = IOUtils.toString(xmlStream, StandardCharsets.UTF_8);
        
        // 3. 封装返回数据
        ProcessDetailVO detail = new ProcessDetailVO();
        detail.setXml(xml);
        detail.setProcessInfo(process);
        
        return detail;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysProcess updateProcess(Long id, String name, String key, MultipartFile file) throws Exception {
        // 1. 验证流程是否存在
        SysProcess process = processMapper.selectById(id);
        if (process == null) {
            throw new RuntimeException("流程不存在");
        }

        // 2. 删除旧的部署
        if (process.getDeploymentId() != null) {
            repositoryService.deleteDeployment(process.getDeploymentId(), true);
        }

        // 3. 部署新的流程
        Deployment deployment = repositoryService.createDeployment()
                .addInputStream(file.getOriginalFilename(), file.getInputStream())
                .name(name)
                .key(key)
                .deploy();
                
        // 4. 获取新的流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();
        
        if (processDefinition == null) {
            throw new RuntimeException("流程部署失败");
        }
        
        // 5. 更新流程信息
        process.setProcessName(name);
        process.setProcessKey(key);
        process.setDeploymentId(deployment.getId());
        process.setProcessDefinitionId(processDefinition.getId());
        process.setVersion(processDefinition.getVersion());
        process.setUpdateTime(new Date());
        
        processMapper.updateById(process);
        
        return process;
    }
} 